/**
 * 统一数据持久化管理工具
 * 支持 LocalStorage、SessionStorage 和 IndexedDB
 * 提供统一的API接口和数据加密功能
 */

import logger from './logger.js'

// 存储类型枚举
export const STORAGE_TYPES = {
  LOCAL: 'localStorage',
  SESSION: 'sessionStorage', 
  INDEXED: 'indexedDB'
}

// 存储键前缀
const STORAGE_PREFIX = 'CRM_TRAVEL_'

// 数据加密/解密(简单Base64，内部使用足够)
const encode = (data) => {
  try {
    return btoa(JSON.stringify(data))
  } catch (error) {
    logger.error('数据编码失败:', error)
    return null
  }
}

const decode = (data) => {
  try {
    return JSON.parse(atob(data))
  } catch (error) {
    logger.error('数据解码失败:', error)
    return null
  }
}

// 添加过期时间支持
const createStorageItem = (data, ttl = null) => {
  const item = {
    data,
    timestamp: Date.now(),
    ttl
  }
  return encode(item)
}

const parseStorageItem = (item) => {
  const decoded = decode(item)
  if (!decoded) return null
  
  // 检查是否过期
  if (decoded.ttl && (Date.now() - decoded.timestamp > decoded.ttl)) {
    return null
  }
  
  return decoded.data
}

// LocalStorage 封装
class LocalStorageManager {
  constructor() {
    this.available = this.checkAvailability()
  }
  
  checkAvailability() {
    try {
      const test = '__storage_test__'
      localStorage.setItem(test, test)
      localStorage.removeItem(test)
      return true
    } catch (error) {
      logger.warn('LocalStorage 不可用:', error)
      return false
    }
  }
  
  set(key, value, ttl = null) {
    if (!this.available) return false
    
    try {
      const storageKey = STORAGE_PREFIX + key
      const storageValue = createStorageItem(value, ttl)
      localStorage.setItem(storageKey, storageValue)
      logger.debug('LocalStorage 存储成功:', { key, ttl })
      return true
    } catch (error) {
      logger.error('LocalStorage 存储失败:', error)
      return false
    }
  }
  
  get(key) {
    if (!this.available) return null
    
    try {
      const storageKey = STORAGE_PREFIX + key
      const item = localStorage.getItem(storageKey)
      if (!item) return null
      
      const data = parseStorageItem(item)
      if (data === null) {
        // 数据已过期，清除
        this.remove(key)
        return null
      }
      
      logger.debug('LocalStorage 读取成功:', { key })
      return data
    } catch (error) {
      logger.error('LocalStorage 读取失败:', error)
      return null
    }
  }
  
  remove(key) {
    if (!this.available) return false
    
    try {
      const storageKey = STORAGE_PREFIX + key
      localStorage.removeItem(storageKey)
      logger.debug('LocalStorage 删除成功:', { key })
      return true
    } catch (error) {
      logger.error('LocalStorage 删除失败:', error)
      return false
    }
  }
  
  clear() {
    if (!this.available) return false
    
    try {
      const keys = Object.keys(localStorage).filter(key => 
        key.startsWith(STORAGE_PREFIX)
      )
      keys.forEach(key => localStorage.removeItem(key))
      logger.info('LocalStorage 清空完成')
      return true
    } catch (error) {
      logger.error('LocalStorage 清空失败:', error)
      return false
    }
  }
  
  getSize() {
    if (!this.available) return 0
    
    let size = 0
    for (let key in localStorage) {
      if (key.startsWith(STORAGE_PREFIX)) {
        size += localStorage.getItem(key).length
      }
    }
    return size
  }
}

// SessionStorage 封装
class SessionStorageManager {
  constructor() {
    this.available = this.checkAvailability()
  }
  
  checkAvailability() {
    try {
      const test = '__session_test__'
      sessionStorage.setItem(test, test)
      sessionStorage.removeItem(test)
      return true
    } catch (error) {
      logger.warn('SessionStorage 不可用:', error)
      return false
    }
  }
  
  set(key, value, ttl = null) {
    if (!this.available) return false
    
    try {
      const storageKey = STORAGE_PREFIX + key
      const storageValue = createStorageItem(value, ttl)
      sessionStorage.setItem(storageKey, storageValue)
      logger.debug('SessionStorage 存储成功:', { key, ttl })
      return true
    } catch (error) {
      logger.error('SessionStorage 存储失败:', error)
      return false
    }
  }
  
  get(key) {
    if (!this.available) return null
    
    try {
      const storageKey = STORAGE_PREFIX + key
      const item = sessionStorage.getItem(storageKey)
      if (!item) return null
      
      const data = parseStorageItem(item)
      if (data === null) {
        this.remove(key)
        return null
      }
      
      logger.debug('SessionStorage 读取成功:', { key })
      return data
    } catch (error) {
      logger.error('SessionStorage 读取失败:', error)
      return null
    }
  }
  
  remove(key) {
    if (!this.available) return false
    
    try {
      const storageKey = STORAGE_PREFIX + key
      sessionStorage.removeItem(storageKey)
      logger.debug('SessionStorage 删除成功:', { key })
      return true
    } catch (error) {
      logger.error('SessionStorage 删除失败:', error)
      return false
    }
  }
  
  clear() {
    if (!this.available) return false
    
    try {
      const keys = Object.keys(sessionStorage).filter(key => 
        key.startsWith(STORAGE_PREFIX)
      )
      keys.forEach(key => sessionStorage.removeItem(key))
      logger.info('SessionStorage 清空完成')
      return true
    } catch (error) {
      logger.error('SessionStorage 清空失败:', error)
      return false
    }
  }
}

// IndexedDB 封装
class IndexedDBManager {
  constructor() {
    this.dbName = 'CRM_TRAVEL_DB'
    this.version = 1
    this.storeName = 'storage'
    this.db = null
    this.available = false
    this.initPromise = this.init()
  }
  
  async init() {
    if (!window.indexedDB) {
      logger.warn('IndexedDB 不可用')
      return false
    }
    
    try {
      this.db = await this.openDatabase()
      this.available = true
      logger.info('IndexedDB 初始化成功')
      return true
    } catch (error) {
      logger.error('IndexedDB 初始化失败:', error)
      return false
    }
  }
  
  openDatabase() {
    return new Promise((resolve, reject) => {
      const request = indexedDB.open(this.dbName, this.version)
      
      request.onerror = () => reject(request.error)
      request.onsuccess = () => resolve(request.result)
      
      request.onupgradeneeded = (event) => {
        const db = event.target.result
        if (!db.objectStoreNames.contains(this.storeName)) {
          const store = db.createObjectStore(this.storeName, { keyPath: 'key' })
          store.createIndex('timestamp', 'timestamp', { unique: false })
        }
      }
    })
  }
  
  async set(key, value, ttl = null) {
    await this.initPromise
    if (!this.available) return false
    
    try {
      const transaction = this.db.transaction([this.storeName], 'readwrite')
      const store = transaction.objectStore(this.storeName)
      
      const item = {
        key: STORAGE_PREFIX + key,
        data: value,
        timestamp: Date.now(),
        ttl
      }
      
      await new Promise((resolve, reject) => {
        const request = store.put(item)
        request.onsuccess = () => resolve()
        request.onerror = () => reject(request.error)
      })
      
      logger.debug('IndexedDB 存储成功:', { key, ttl })
      return true
    } catch (error) {
      logger.error('IndexedDB 存储失败:', error)
      return false
    }
  }
  
  async get(key) {
    await this.initPromise
    if (!this.available) return null
    
    try {
      const transaction = this.db.transaction([this.storeName], 'readonly')
      const store = transaction.objectStore(this.storeName)
      
      const item = await new Promise((resolve, reject) => {
        const request = store.get(STORAGE_PREFIX + key)
        request.onsuccess = () => resolve(request.result)
        request.onerror = () => reject(request.error)
      })
      
      if (!item) return null
      
      // 检查是否过期
      if (item.ttl && (Date.now() - item.timestamp > item.ttl)) {
        await this.remove(key)
        return null
      }
      
      logger.debug('IndexedDB 读取成功:', { key })
      return item.data
    } catch (error) {
      logger.error('IndexedDB 读取失败:', error)
      return null
    }
  }
  
  async remove(key) {
    await this.initPromise
    if (!this.available) return false
    
    try {
      const transaction = this.db.transaction([this.storeName], 'readwrite')
      const store = transaction.objectStore(this.storeName)
      
      await new Promise((resolve, reject) => {
        const request = store.delete(STORAGE_PREFIX + key)
        request.onsuccess = () => resolve()
        request.onerror = () => reject(request.error)
      })
      
      logger.debug('IndexedDB 删除成功:', { key })
      return true
    } catch (error) {
      logger.error('IndexedDB 删除失败:', error)
      return false
    }
  }
  
  async clear() {
    await this.initPromise
    if (!this.available) return false
    
    try {
      const transaction = this.db.transaction([this.storeName], 'readwrite')
      const store = transaction.objectStore(this.storeName)
      
      await new Promise((resolve, reject) => {
        const request = store.clear()
        request.onsuccess = () => resolve()
        request.onerror = () => reject(request.error)
      })
      
      logger.info('IndexedDB 清空完成')
      return true
    } catch (error) {
      logger.error('IndexedDB 清空失败:', error)
      return false
    }
  }
}

// 统一存储管理器
class StorageManager {
  constructor() {
    this.local = new LocalStorageManager()
    this.session = new SessionStorageManager()
    this.indexed = new IndexedDBManager()
  }
  
  // 智能存储选择
  async set(key, value, options = {}) {
    const {
      type = 'auto',
      ttl = null,
      compress = false
    } = options
    
    let targetStorage = type
    
    // 自动选择存储类型
    if (type === 'auto') {
      const dataSize = JSON.stringify(value).length
      
      if (dataSize > 5 * 1024 * 1024) { // > 5MB
        targetStorage = STORAGE_TYPES.INDEXED
      } else if (ttl && ttl < 60 * 60 * 1000) { // < 1小时
        targetStorage = STORAGE_TYPES.SESSION
      } else {
        targetStorage = STORAGE_TYPES.LOCAL
      }
    }
    
    // 执行存储
    switch (targetStorage) {
      case STORAGE_TYPES.LOCAL:
        return this.local.set(key, value, ttl)
      case STORAGE_TYPES.SESSION:
        return this.session.set(key, value, ttl)
      case STORAGE_TYPES.INDEXED:
        return await this.indexed.set(key, value, ttl)
      default:
        logger.error('不支持的存储类型:', targetStorage)
        return false
    }
  }
  
  // 智能读取
  async get(key, fallbackTypes = [STORAGE_TYPES.LOCAL, STORAGE_TYPES.SESSION, STORAGE_TYPES.INDEXED]) {
    for (const type of fallbackTypes) {
      let result = null
      
      switch (type) {
        case STORAGE_TYPES.LOCAL:
          result = this.local.get(key)
          break
        case STORAGE_TYPES.SESSION:
          result = this.session.get(key)
          break
        case STORAGE_TYPES.INDEXED:
          result = await this.indexed.get(key)
          break
      }
      
      if (result !== null) {
        return result
      }
    }
    
    return null
  }
  
  // 从所有存储中删除
  async remove(key) {
    const results = await Promise.all([
      this.local.remove(key),
      this.session.remove(key),
      this.indexed.remove(key)
    ])
    
    return results.some(result => result)
  }
  
  // 清空所有存储
  async clear() {
    const results = await Promise.all([
      this.local.clear(),
      this.session.clear(),
      this.indexed.clear()
    ])
    
    return results.every(result => result)
  }
  
  // 获取存储使用情况
  async getStorageInfo() {
    const info = {
      localStorage: {
        available: this.local.available,
        size: this.local.getSize(),
        quota: 10 * 1024 * 1024 // 约10MB
      },
      sessionStorage: {
        available: this.session.available,
        size: 0, // SessionStorage size calculation
        quota: 10 * 1024 * 1024
      },
      indexedDB: {
        available: this.indexed.available,
        size: 0, // IndexedDB size calculation is complex
        quota: 1024 * 1024 * 1024 // 约1GB
      }
    }
    
    return info
  }
}

// 预设的存储键常量
export const STORAGE_KEYS = {
  // 用户相关
  USER_PREFERENCES: 'user_preferences',
  USER_SETTINGS: 'user_settings',
  USER_THEME: 'user_theme',
  
  // 业务数据缓存
  CUSTOMER_LIST_CACHE: 'customer_list_cache',
  PRODUCT_LIST_CACHE: 'product_list_cache',
  DASHBOARD_DATA_CACHE: 'dashboard_data_cache',
  
  // 表单数据
  FORM_DRAFT_PREFIX: 'form_draft_',
  SEARCH_HISTORY: 'search_history',
  
  // 系统状态
  LAST_ROUTE: 'last_route',
  SIDEBAR_COLLAPSED: 'sidebar_collapsed',
  TABLE_COLUMNS_STATE: 'table_columns_state',
  
  // 临时数据
  TEMP_DATA_PREFIX: 'temp_data_'
}

// 创建全局存储管理器实例
const storage = new StorageManager()

// 便捷方法
export const userPreferences = {
  get: () => storage.get(STORAGE_KEYS.USER_PREFERENCES),
  set: (data) => storage.set(STORAGE_KEYS.USER_PREFERENCES, data, { type: STORAGE_TYPES.LOCAL }),
  update: async (updates) => {
    const current = await userPreferences.get() || {}
    return userPreferences.set({ ...current, ...updates })
  }
}

export const formDraft = {
  save: (formId, data) => storage.set(
    STORAGE_KEYS.FORM_DRAFT_PREFIX + formId, 
    data, 
    { type: STORAGE_TYPES.SESSION, ttl: 24 * 60 * 60 * 1000 } // 24小时
  ),
  load: (formId) => storage.get(STORAGE_KEYS.FORM_DRAFT_PREFIX + formId),
  clear: (formId) => storage.remove(STORAGE_KEYS.FORM_DRAFT_PREFIX + formId)
}

export const cacheManager = {
  set: (key, data, ttl = 30 * 60 * 1000) => storage.set(key, data, { ttl }), // 默认30分钟
  get: (key) => storage.get(key),
  invalidate: (key) => storage.remove(key),
  invalidatePattern: async (pattern) => {
    // 简单的模式匹配清除
    const keys = Object.keys(localStorage).filter(key => 
      key.includes(STORAGE_PREFIX) && key.includes(pattern)
    )
    for (const key of keys) {
      await storage.remove(key.replace(STORAGE_PREFIX, ''))
    }
  }
}

export default storage